﻿using SoftFloat;
using System;
using System.Runtime.CompilerServices;

namespace BepuUtilities
{
    public static class Scalar<T>
    {
        public static T AllBitsSet
        {
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            get
            {
                if (typeof(T) == typeof(byte))
                {
                    return (T)((object)byte.MaxValue);
                }
                if (typeof(T) == typeof(double))
                {
                    return (T)((object)BitConverter.Int64BitsToDouble(-1L));
                }
                if (typeof(T) == typeof(short))
                {
                    return (T)((object)-1);
                }
                if (typeof(T) == typeof(int))
                {
                    return (T)((object)-1);
                }
                if (typeof(T) == typeof(long))
                {
                    return (T)((object)-1L);
                }
                if (typeof(T) == typeof(IntPtr))
                {
                    return (T)((object)((IntPtr)(-1)));
                }
                if (typeof(T) == typeof(UIntPtr))
                {
                    return (T)((object)UIntPtr.MaxValue);
                }
                if (typeof(T) == typeof(sbyte))
                {
                    return (T)((object)-1);
                }
                if (typeof(T) == typeof(sfloat))
                {
                    return (T)(object)Unsafe.BitCast<int, sfloat>(-1);//BitConverter.Int32BitsToSingle(-1);
                }
                if (typeof(T) == typeof(ushort))
                {
                    return (T)((object)ushort.MaxValue);
                }
                if (typeof(T) == typeof(uint))
                {
                    return (T)((object)uint.MaxValue);
                }
                if (typeof(T) == typeof(ulong))
                {
                    return (T)((object)ulong.MaxValue);
                }
                //ThrowHelper.ThrowNotSupportedException(ExceptionResource.Arg_TypeNotSupported);
                return default(T);
            }
        }

        public static T One
        {
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            get
            {
                if (typeof(T) == typeof(byte))
                {
                    return (T)((object)1);
                }
                if (typeof(T) == typeof(double))
                {
                    return (T)((object)1.0);
                }
                if (typeof(T) == typeof(short))
                {
                    return (T)((object)1);
                }
                if (typeof(T) == typeof(int))
                {
                    return (T)((object)1);
                }
                if (typeof(T) == typeof(long))
                {
                    return (T)((object)1L);
                }
                if (typeof(T) == typeof(IntPtr))
                {
                    return (T)((object)((IntPtr)1));
                }
                if (typeof(T) == typeof(UIntPtr))
                {
                    return (T)((object)((UIntPtr)((IntPtr)1)));
                }
                if (typeof(T) == typeof(sbyte))
                {
                    return (T)((object)1);
                }
                if (typeof(T) == typeof(sfloat))
                {
                    return (T)(object)(sfloat)1f;
                }
                if (typeof(T) == typeof(ushort))
                {
                    return (T)((object)1);
                }
                if (typeof(T) == typeof(uint))
                {
                    return (T)((object)1U);
                }
                if (typeof(T) == typeof(ulong))
                {
                    return (T)((object)1UL);
                }
                //ThrowHelper.ThrowNotSupportedException(ExceptionResource.Arg_TypeNotSupported);
                return default(T);
            }
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static T Abs(T value)
        {
            if (typeof(T) == typeof(double))
            {
                return (T)((object)Math.Abs((double)((object)value)));
            }
            if (typeof(T) == typeof(short))
            {
                return (T)((object)Math.Abs((short)((object)value)));
            }
            if (typeof(T) == typeof(int))
            {
                return (T)((object)Math.Abs((int)((object)value)));
            }
            if (typeof(T) == typeof(long))
            {
                return (T)((object)Math.Abs((long)((object)value)));
            }
            if (typeof(T) == typeof(IntPtr))
            {
                return (T)((object)Math.Abs((IntPtr)((object)value)));
            }
            if (typeof(T) == typeof(sbyte))
            {
                return (T)((object)Math.Abs((sbyte)((object)value)));
            }
            if (typeof(T) == typeof(sfloat))
            {
                return (T)(object)libm.Abs((sfloat)(object)value);
            }
            //ThrowHelper.ThrowNotSupportedException(ExceptionResource.Arg_TypeNotSupported);
            return default;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static T Add(T left, T right)
        {
            if (typeof(T) == typeof(byte))
            {
                return (T)((object)((byte)((object)left) + (byte)((object)right)));
            }
            if (typeof(T) == typeof(double))
            {
                return (T)((object)((double)((object)left) + (double)((object)right)));
            }
            if (typeof(T) == typeof(short))
            {
                return (T)((object)((short)((object)left) + (short)((object)right)));
            }
            if (typeof(T) == typeof(int))
            {
                return (T)((object)((int)((object)left) + (int)((object)right)));
            }
            if (typeof(T) == typeof(long))
            {
                return (T)((object)((long)((object)left) + (long)((object)right)));
            }
            if (typeof(T) == typeof(IntPtr))
            {
                return (T)((object)((IntPtr)((object)left) + (IntPtr)((object)right)));
            }
            if (typeof(T) == typeof(UIntPtr))
            {
                return (T)((object)((UIntPtr)((object)left) + (UIntPtr)((object)right)));
            }
            if (typeof(T) == typeof(sbyte))
            {
                return (T)((object)((sbyte)((object)left) + (sbyte)((object)right)));
            }
            if (typeof(T) == typeof(sfloat))
            {
                return (T)((object)((sfloat)((object)left) + (sfloat)((object)right)));
            }
            if (typeof(T) == typeof(ushort))
            {
                return (T)((object)((ushort)((object)left) + (ushort)((object)right)));
            }
            if (typeof(T) == typeof(uint))
            {
                return (T)((object)((uint)((object)left) + (uint)((object)right)));
            }
            if (typeof(T) == typeof(ulong))
            {
                return (T)((object)((ulong)((object)left) + (ulong)((object)right)));
            }
            //ThrowHelper.ThrowNotSupportedException(ExceptionResource.Arg_TypeNotSupported);
            return default(T);
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static T Ceiling(T value)
        {
            if (typeof(T) == typeof(double))
            {
                return (T)((object)Math.Ceiling((double)((object)value)));
            }
            if (typeof(T) == typeof(sfloat))
            {
                return (T)((object)MathF.Ceiling((sfloat)((object)value)));
            }
            //ThrowHelper.ThrowNotSupportedException(ExceptionResource.Arg_TypeNotSupported);
            return default(T);
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static T Divide(T left, T right)
        {
            if (typeof(T) == typeof(byte))
            {
                return (T)((object)((byte)((object)left) / (byte)((object)right)));
            }
            if (typeof(T) == typeof(double))
            {
                return (T)((object)((double)((object)left) / (double)((object)right)));
            }
            if (typeof(T) == typeof(short))
            {
                return (T)((object)((short)((object)left) / (short)((object)right)));
            }
            if (typeof(T) == typeof(int))
            {
                return (T)((object)((int)((object)left) / (int)((object)right)));
            }
            if (typeof(T) == typeof(long))
            {
                return (T)((object)((long)((object)left) / (long)((object)right)));
            }
            if (typeof(T) == typeof(IntPtr))
            {
                return (T)((object)((IntPtr)((object)left) / (IntPtr)((object)right)));
            }
            if (typeof(T) == typeof(UIntPtr))
            {
                return (T)((object)((UIntPtr)((object)left) / (UIntPtr)((object)right)));
            }
            if (typeof(T) == typeof(sbyte))
            {
                return (T)((object)((sbyte)((object)left) / (sbyte)((object)right)));
            }
            if (typeof(T) == typeof(sfloat))
            {
                return (T)((object)((sfloat)((object)left) / (sfloat)((object)right)));
            }
            if (typeof(T) == typeof(ushort))
            {
                return (T)((object)((ushort)((object)left) / (ushort)((object)right)));
            }
            if (typeof(T) == typeof(uint))
            {
                return (T)((object)((uint)((object)left) / (uint)((object)right)));
            }
            if (typeof(T) == typeof(ulong))
            {
                return (T)((object)((ulong)((object)left) / (ulong)((object)right)));
            }
            //ThrowHelper.ThrowNotSupportedException(ExceptionResource.Arg_TypeNotSupported);
            return default(T);
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static bool Equals(T left, T right)
        {
            if (typeof(T) == typeof(byte))
            {
                return (byte)((object)left) == (byte)((object)right);
            }
            if (typeof(T) == typeof(double))
            {
                return (double)((object)left) == (double)((object)right);
            }
            if (typeof(T) == typeof(short))
            {
                return (short)((object)left) == (short)((object)right);
            }
            if (typeof(T) == typeof(int))
            {
                return (int)((object)left) == (int)((object)right);
            }
            if (typeof(T) == typeof(long))
            {
                return (long)((object)left) == (long)((object)right);
            }
            if (typeof(T) == typeof(IntPtr))
            {
                return (IntPtr)((object)left) == (IntPtr)((object)right);
            }
            if (typeof(T) == typeof(UIntPtr))
            {
                return (UIntPtr)((object)left) == (UIntPtr)((object)right);
            }
            if (typeof(T) == typeof(sbyte))
            {
                return (sbyte)((object)left) == (sbyte)((object)right);
            }
            if (typeof(T) == typeof(sfloat))
            {
                return (sfloat)((object)left) == (sfloat)((object)right);
            }
            if (typeof(T) == typeof(ushort))
            {
                return (ushort)((object)left) == (ushort)((object)right);
            }
            if (typeof(T) == typeof(uint))
            {
                return (uint)((object)left) == (uint)((object)right);
            }
            if (typeof(T) == typeof(ulong))
            {
                return (ulong)((object)left) == (ulong)((object)right);
            }
            //ThrowHelper.ThrowNotSupportedException(ExceptionResource.Arg_TypeNotSupported);
            return false;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static uint ExtractMostSignificantBit(T value)
        {
            if (typeof(T) == typeof(byte))
            {
                uint num = (uint)((byte)((object)value));
                return num >> 7;
            }
            if (typeof(T) == typeof(double))
            {
                ulong num2 = BitConverter.DoubleToUInt64Bits((double)((object)value));
                return (uint)(num2 >> 63);
            }
            if (typeof(T) == typeof(short))
            {
                uint num3 = (uint)((ushort)((short)((object)value)));
                return num3 >> 15;
            }
            if (typeof(T) == typeof(int))
            {
                uint num4 = (uint)((int)((object)value));
                return num4 >> 31;
            }
            if (typeof(T) == typeof(long))
            {
                ulong num5 = (ulong)((long)((object)value));
                return (uint)(num5 >> 63);
            }
            if (typeof(T) == typeof(IntPtr))
            {
                ulong num6 = (ulong)((long)((IntPtr)((object)value)));
                return (uint)(num6 >> 63);
            }
            if (typeof(T) == typeof(UIntPtr))
            {
                ulong num7 = (ulong)((UIntPtr)((object)value));
                return (uint)(num7 >> 63);
            }
            if (typeof(T) == typeof(sbyte))
            {
                uint num8 = (uint)((byte)((sbyte)((object)value)));
                return num8 >> 7;
            }
            if (typeof(T) == typeof(sfloat))
            {
                uint num9 = BitConverter.SingleToUInt32Bits((sfloat)((object)value));
                return num9 >> 31;
            }
            if (typeof(T) == typeof(ushort))
            {
                uint num10 = (uint)((ushort)((object)value));
                return num10 >> 15;
            }
            if (typeof(T) == typeof(uint))
            {
                uint num11 = (uint)((object)value);
                return num11 >> 31;
            }
            if (typeof(T) == typeof(ulong))
            {
                ulong num12 = (ulong)((object)value);
                return (uint)(num12 >> 63);
            }
            //ThrowHelper.ThrowNotSupportedException(ExceptionResource.Arg_TypeNotSupported);
            return 0U;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static T Floor(T value)
        {
            if (typeof(T) == typeof(double))
            {
                return (T)((object)Math.Floor((double)((object)value)));
            }
            if (typeof(T) == typeof(sfloat))
            {
                if (value is sfloat sfloat) 
                {
                    return (T)(object)libm.Floor(sfloat);
                }
            }
            //ThrowHelper.ThrowNotSupportedException(ExceptionResource.Arg_TypeNotSupported);
            return default;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static bool GreaterThan(T left, T right)
        {
            if (typeof(T) == typeof(byte))
            {
                return (byte)((object)left) > (byte)((object)right);
            }
            if (typeof(T) == typeof(double))
            {
                return (double)((object)left) > (double)((object)right);
            }
            if (typeof(T) == typeof(short))
            {
                return (short)((object)left) > (short)((object)right);
            }
            if (typeof(T) == typeof(int))
            {
                return (int)((object)left) > (int)((object)right);
            }
            if (typeof(T) == typeof(long))
            {
                return (long)((object)left) > (long)((object)right);
            }
            if (typeof(T) == typeof(IntPtr))
            {
                return (IntPtr)((object)left) > (IntPtr)((object)right);
            }
            if (typeof(T) == typeof(UIntPtr))
            {
                return (UIntPtr)((object)left) > (UIntPtr)((object)right);
            }
            if (typeof(T) == typeof(sbyte))
            {
                return (sbyte)((object)left) > (sbyte)((object)right);
            }
            if (typeof(T) == typeof(sfloat))
            {
                return (sfloat)((object)left) > (sfloat)((object)right);
            }
            if (typeof(T) == typeof(ushort))
            {
                return (ushort)((object)left) > (ushort)((object)right);
            }
            if (typeof(T) == typeof(uint))
            {
                return (uint)((object)left) > (uint)((object)right);
            }
            if (typeof(T) == typeof(ulong))
            {
                return (ulong)((object)left) > (ulong)((object)right);
            }
            //ThrowHelper.ThrowNotSupportedException(ExceptionResource.Arg_TypeNotSupported);
            return false;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static bool GreaterThanOrEqual(T left, T right)
        {
            if (typeof(T) == typeof(byte))
            {
                return (byte)((object)left) >= (byte)((object)right);
            }
            if (typeof(T) == typeof(double))
            {
                return (double)((object)left) >= (double)((object)right);
            }
            if (typeof(T) == typeof(short))
            {
                return (short)((object)left) >= (short)((object)right);
            }
            if (typeof(T) == typeof(int))
            {
                return (int)((object)left) >= (int)((object)right);
            }
            if (typeof(T) == typeof(long))
            {
                return (long)((object)left) >= (long)((object)right);
            }
            if (typeof(T) == typeof(IntPtr))
            {
                return (IntPtr)((object)left) >= (IntPtr)((object)right);
            }
            if (typeof(T) == typeof(UIntPtr))
            {
                return (UIntPtr)((object)left) >= (UIntPtr)((object)right);
            }
            if (typeof(T) == typeof(sbyte))
            {
                return (sbyte)((object)left) >= (sbyte)((object)right);
            }
            if (typeof(T) == typeof(sfloat))
            {
                return (sfloat)((object)left) >= (sfloat)((object)right);
            }
            if (typeof(T) == typeof(ushort))
            {
                return (ushort)((object)left) >= (ushort)((object)right);
            }
            if (typeof(T) == typeof(uint))
            {
                return (uint)((object)left) >= (uint)((object)right);
            }
            if (typeof(T) == typeof(ulong))
            {
                return (ulong)((object)left) >= (ulong)((object)right);
            }
            //ThrowHelper.ThrowNotSupportedException(ExceptionResource.Arg_TypeNotSupported);
            return false;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static bool LessThan(T left, T right)
        {
            if (typeof(T) == typeof(byte))
            {
                return (byte)((object)left) < (byte)((object)right);
            }
            if (typeof(T) == typeof(double))
            {
                return (double)((object)left) < (double)((object)right);
            }
            if (typeof(T) == typeof(short))
            {
                return (short)((object)left) < (short)((object)right);
            }
            if (typeof(T) == typeof(int))
            {
                return (int)((object)left) < (int)((object)right);
            }
            if (typeof(T) == typeof(long))
            {
                return (long)((object)left) < (long)((object)right);
            }
            if (typeof(T) == typeof(IntPtr))
            {
                return (IntPtr)((object)left) < (IntPtr)((object)right);
            }
            if (typeof(T) == typeof(UIntPtr))
            {
                return (UIntPtr)((object)left) < (UIntPtr)((object)right);
            }
            if (typeof(T) == typeof(sbyte))
            {
                return (sbyte)((object)left) < (sbyte)((object)right);
            }
            if (typeof(T) == typeof(sfloat))
            {
                return (sfloat)((object)left) < (sfloat)((object)right);
            }
            if (typeof(T) == typeof(ushort))
            {
                return (ushort)((object)left) < (ushort)((object)right);
            }
            if (typeof(T) == typeof(uint))
            {
                return (uint)((object)left) < (uint)((object)right);
            }
            if (typeof(T) == typeof(ulong))
            {
                return (ulong)((object)left) < (ulong)((object)right);
            }
            //ThrowHelper.ThrowNotSupportedException(ExceptionResource.Arg_TypeNotSupported);
            return false;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static bool LessThanOrEqual(T left, T right)
        {
            if (typeof(T) == typeof(byte))
            {
                return (byte)((object)left) <= (byte)((object)right);
            }
            if (typeof(T) == typeof(double))
            {
                return (double)((object)left) <= (double)((object)right);
            }
            if (typeof(T) == typeof(short))
            {
                return (short)((object)left) <= (short)((object)right);
            }
            if (typeof(T) == typeof(int))
            {
                return (int)((object)left) <= (int)((object)right);
            }
            if (typeof(T) == typeof(long))
            {
                return (long)((object)left) <= (long)((object)right);
            }
            if (typeof(T) == typeof(IntPtr))
            {
                return (IntPtr)((object)left) <= (IntPtr)((object)right);
            }
            if (typeof(T) == typeof(UIntPtr))
            {
                return (UIntPtr)((object)left) <= (UIntPtr)((object)right);
            }
            if (typeof(T) == typeof(sbyte))
            {
                return (sbyte)((object)left) <= (sbyte)((object)right);
            }
            if (typeof(T) == typeof(sfloat))
            {
                return (sfloat)((object)left) <= (sfloat)((object)right);
            }
            if (typeof(T) == typeof(ushort))
            {
                return (ushort)((object)left) <= (ushort)((object)right);
            }
            if (typeof(T) == typeof(uint))
            {
                return (uint)((object)left) <= (uint)((object)right);
            }
            if (typeof(T) == typeof(ulong))
            {
                return (ulong)((object)left) <= (ulong)((object)right);
            }
            //ThrowHelper.ThrowNotSupportedException(ExceptionResource.Arg_TypeNotSupported);
            return false;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static T Multiply(T left, T right)
        {
            if (typeof(T) == typeof(byte))
            {
                return (T)((object)((byte)((object)left) * (byte)((object)right)));
            }
            if (typeof(T) == typeof(double))
            {
                return (T)((object)((double)((object)left) * (double)((object)right)));
            }
            if (typeof(T) == typeof(short))
            {
                return (T)((object)((short)((object)left) * (short)((object)right)));
            }
            if (typeof(T) == typeof(int))
            {
                return (T)((object)((int)((object)left) * (int)((object)right)));
            }
            if (typeof(T) == typeof(long))
            {
                return (T)((object)((long)((object)left) * (long)((object)right)));
            }
            if (typeof(T) == typeof(IntPtr))
            {
                return (T)((object)((IntPtr)((object)left) * (IntPtr)((object)right)));
            }
            if (typeof(T) == typeof(UIntPtr))
            {
                return (T)((object)((UIntPtr)((object)left) * (UIntPtr)((object)right)));
            }
            if (typeof(T) == typeof(sbyte))
            {
                return (T)((object)((sbyte)((object)left) * (sbyte)((object)right)));
            }
            if (typeof(T) == typeof(sfloat))
            {
                return (T)((object)((sfloat)((object)left) * (sfloat)((object)right)));
            }
            if (typeof(T) == typeof(ushort))
            {
                return (T)((object)((ushort)((object)left) * (ushort)((object)right)));
            }
            if (typeof(T) == typeof(uint))
            {
                return (T)((object)((uint)((object)left) * (uint)((object)right)));
            }
            if (typeof(T) == typeof(ulong))
            {
                return (T)((object)((ulong)((object)left) * (ulong)((object)right)));
            }
            //ThrowHelper.ThrowNotSupportedException(ExceptionResource.Arg_TypeNotSupported);
            return default(T);
        }

        public static bool ObjectEquals(T left, T right)
        {
            if (typeof(T) == typeof(byte))
            {
                return ((byte)((object)left)).Equals((byte)((object)right));
            }
            if (typeof(T) == typeof(double))
            {
                return ((double)((object)left)).Equals((double)((object)right));
            }
            if (typeof(T) == typeof(short))
            {
                return ((short)((object)left)).Equals((short)((object)right));
            }
            if (typeof(T) == typeof(int))
            {
                return ((int)((object)left)).Equals((int)((object)right));
            }
            if (typeof(T) == typeof(long))
            {
                return ((long)((object)left)).Equals((long)((object)right));
            }
            if (typeof(T) == typeof(IntPtr))
            {
                return ((IntPtr)((object)left)).Equals((IntPtr)((object)right));
            }
            if (typeof(T) == typeof(UIntPtr))
            {
                return ((UIntPtr)((object)left)).Equals((UIntPtr)((object)right));
            }
            if (typeof(T) == typeof(sbyte))
            {
                return ((sbyte)((object)left)).Equals((sbyte)((object)right));
            }
            if (typeof(T) == typeof(sfloat))
            {
                return ((sfloat)((object)left)).Equals((sfloat)((object)right));
            }
            if (typeof(T) == typeof(ushort))
            {
                return ((ushort)((object)left)).Equals((ushort)((object)right));
            }
            if (typeof(T) == typeof(uint))
            {
                return ((uint)((object)left)).Equals((uint)((object)right));
            }
            if (typeof(T) == typeof(ulong))
            {
                return ((ulong)((object)left)).Equals((ulong)((object)right));
            }
            //ThrowHelper.ThrowNotSupportedException(ExceptionResource.Arg_TypeNotSupported);
            return false;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static T ShiftLeft(T value, int shiftCount)
        {
            if (typeof(T) == typeof(byte))
            {
                return (T)((object)((byte)((byte)((object)value) << (shiftCount & 7))));
            }
            if (typeof(T) == typeof(double))
            {
                long num = BitConverter.DoubleToInt64Bits((double)((object)value));
                double num2 = BitConverter.Int64BitsToDouble(num << shiftCount);
                return (T)((object)num2);
            }
            if (typeof(T) == typeof(short))
            {
                return (T)((object)((short)((short)((object)value) << (shiftCount & 15))));
            }
            if (typeof(T) == typeof(int))
            {
                return (T)((object)((int)((object)value) << shiftCount));
            }
            if (typeof(T) == typeof(long))
            {
                return (T)((object)((long)((object)value) << shiftCount));
            }
            if (typeof(T) == typeof(IntPtr))
            {
                return (T)((object)((IntPtr)((object)value) << (shiftCount & 8 * 8 - 1)));
            }
            if (typeof(T) == typeof(UIntPtr))
            {
                return (T)((object)((UIntPtr)((object)value) << (shiftCount & 8 * 8 - 1)));
            }
            if (typeof(T) == typeof(sbyte))
            {
                return (T)((object)((sbyte)((sbyte)((object)value) << (shiftCount & 7))));
            }
            if (typeof(T) == typeof(sfloat))
            {
                int num3 = BitConverter.SingleToInt32Bits((sfloat)((object)value));
                sfloat num4 = BitConverter.Int32BitsToSingle(num3 << shiftCount);
                return (T)((object)num4);
            }
            if (typeof(T) == typeof(ushort))
            {
                return (T)((object)((ushort)((ushort)((object)value) << (shiftCount & 15))));
            }
            if (typeof(T) == typeof(uint))
            {
                return (T)((object)((uint)((object)value) << shiftCount));
            }
            if (typeof(T) == typeof(ulong))
            {
                return (T)((object)((ulong)((object)value) << shiftCount));
            }
            //ThrowHelper.ThrowNotSupportedException(ExceptionResource.Arg_TypeNotSupported);
            return default(T);
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static T ShiftRightArithmetic(T value, int shiftCount)
        {
            if (typeof(T) == typeof(byte))
            {
                return (T)((object)((byte)((byte)((object)value) >> (shiftCount & 7))));
            }
            if (typeof(T) == typeof(double))
            {
                long num = BitConverter.DoubleToInt64Bits((double)((object)value));
                double num2 = BitConverter.Int64BitsToDouble(num >> shiftCount);
                return (T)((object)num2);
            }
            if (typeof(T) == typeof(short))
            {
                return (T)((object)((short)((short)((object)value) >> (shiftCount & 15))));
            }
            if (typeof(T) == typeof(int))
            {
                return (T)((object)((int)((object)value) >> shiftCount));
            }
            if (typeof(T) == typeof(long))
            {
                return (T)((object)((long)((object)value) >> shiftCount));
            }
            if (typeof(T) == typeof(IntPtr))
            {
                return (T)((object)((IntPtr)((object)value) >> (shiftCount & 8 * 8 - 1)));
            }
            if (typeof(T) == typeof(UIntPtr))
            {
                return (T)((object)((UIntPtr)((object)value) >> (shiftCount & 8 * 8 - 1)));
            }
            if (typeof(T) == typeof(sbyte))
            {
                return (T)((object)((sbyte)((sbyte)((object)value) >> (shiftCount & 7))));
            }
            if (typeof(T) == typeof(sfloat))
            {
                int num3 = BitConverter.SingleToInt32Bits((sfloat)((object)value));
                sfloat num4 = BitConverter.Int32BitsToSingle(num3 >> shiftCount);
                return (T)((object)num4);
            }
            if (typeof(T) == typeof(ushort))
            {
                return (T)((object)((ushort)((ushort)((object)value) >> (shiftCount & 15))));
            }
            if (typeof(T) == typeof(uint))
            {
                return (T)((object)((uint)((object)value) >> shiftCount));
            }
            if (typeof(T) == typeof(ulong))
            {
                return (T)((object)((ulong)((object)value) >> shiftCount));
            }
            //ThrowHelper.ThrowNotSupportedException(ExceptionResource.Arg_TypeNotSupported);
            return default(T);
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static T ShiftRightLogical(T value, int shiftCount)
        {
            if (typeof(T) == typeof(byte))
            {
                return (T)((object)((byte)((uint)((byte)((object)value)) >> (shiftCount & 7))));
            }
            if (typeof(T) == typeof(double))
            {
                long num = BitConverter.DoubleToInt64Bits((double)((object)value));
                double num2 = BitConverter.Int64BitsToDouble((long)((ulong)num >> shiftCount));
                return (T)((object)num2);
            }
            if (typeof(T) == typeof(short))
            {
                return (T)((object)((short)((uint)((ushort)((short)((object)value))) >> (shiftCount & 15))));
            }
            if (typeof(T) == typeof(int))
            {
                return (T)((object)((int)((uint)((int)((object)value)) >> shiftCount)));
            }
            if (typeof(T) == typeof(long))
            {
                return (T)((object)((long)((ulong)((long)((object)value)) >> shiftCount)));
            }
            if (typeof(T) == typeof(IntPtr))
            {
                return (T)((object)((IntPtr)((object)value) >> (shiftCount & 8 * 8 - 1)));
            }
            if (typeof(T) == typeof(UIntPtr))
            {
                return (T)((object)((UIntPtr)((object)value) >> (shiftCount & 8 * 8 - 1)));
            }
            if (typeof(T) == typeof(sbyte))
            {
                return (T)((object)((sbyte)((uint)((byte)((sbyte)((object)value))) >> (shiftCount & 7))));
            }
            if (typeof(T) == typeof(sfloat))
            {
                int num3 = BitConverter.SingleToInt32Bits((sfloat)((object)value));
                sfloat num4 = BitConverter.Int32BitsToSingle((int)((uint)num3 >> shiftCount));
                return (T)((object)num4);
            }
            if (typeof(T) == typeof(ushort))
            {
                return (T)((object)((ushort)((uint)((ushort)((object)value)) >> (shiftCount & 15))));
            }
            if (typeof(T) == typeof(uint))
            {
                return (T)((object)((uint)((object)value) >> shiftCount));
            }
            if (typeof(T) == typeof(ulong))
            {
                return (T)((object)((ulong)((object)value) >> shiftCount));
            }
            //ThrowHelper.ThrowNotSupportedException(ExceptionResource.Arg_TypeNotSupported);
            return default(T);
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static T Sqrt(T value)
        {
            if (typeof(T) == typeof(byte))
            {
                return (T)((object)((byte)MathF.Sqrt((sfloat)((byte)((object)value)))));
            }
            if (typeof(T) == typeof(double))
            {
                return (T)((object)Math.Sqrt((double)((object)value)));
            }
            if (typeof(T) == typeof(short))
            {
                return (T)((object)((short)MathF.Sqrt((sfloat)((short)((object)value)))));
            }
            if (typeof(T) == typeof(int))
            {
                return (T)((object)((int)Math.Sqrt((double)((int)((object)value)))));
            }
            if (typeof(T) == typeof(long))
            {
                return (T)((object)((long)Math.Sqrt((double)((long)((object)value)))));
            }
            if (typeof(T) == typeof(IntPtr))
            {
                return (T)((object)((IntPtr)Math.Sqrt((double)((IntPtr)((object)value)))));
            }
            if (typeof(T) == typeof(UIntPtr))
            {
                return (T)((object)((UIntPtr)Math.Sqrt((UIntPtr)((object)value))));
            }
            if (typeof(T) == typeof(sbyte))
            {
                return (T)((object)((sbyte)MathF.Sqrt((sfloat)((sbyte)((object)value)))));
            }
            if (typeof(T) == typeof(sfloat))
            {
                return (T)(object)libm.Sqrt((sfloat)(object)value);
            }
            if (typeof(T) == typeof(ushort))
            {
                return (T)((object)((ushort)MathF.Sqrt((sfloat)((ushort)((object)value)))));
            }
            if (typeof(T) == typeof(uint))
            {
                return (T)((object)((uint)Math.Sqrt((uint)((object)value))));
            }
            if (typeof(T) == typeof(ulong))
            {
                return (T)((object)((ulong)Math.Sqrt((ulong)((object)value))));
            }
            //ThrowHelper.ThrowNotSupportedException(ExceptionResource.Arg_TypeNotSupported);
            return default(T);
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static T Subtract(T left, T right)
        {
            if (typeof(T) == typeof(byte))
            {
                return (T)((object)((byte)((object)left) - (byte)((object)right)));
            }
            if (typeof(T) == typeof(double))
            {
                return (T)((object)((double)((object)left) - (double)((object)right)));
            }
            if (typeof(T) == typeof(short))
            {
                return (T)((object)((short)((object)left) - (short)((object)right)));
            }
            if (typeof(T) == typeof(int))
            {
                return (T)((object)((int)((object)left) - (int)((object)right)));
            }
            if (typeof(T) == typeof(long))
            {
                return (T)((object)((long)((object)left) - (long)((object)right)));
            }
            if (typeof(T) == typeof(IntPtr))
            {
                return (T)((object)((IntPtr)((object)left) - (IntPtr)((object)right)));
            }
            if (typeof(T) == typeof(UIntPtr))
            {
                return (T)((object)((UIntPtr)((object)left) - (UIntPtr)((object)right)));
            }
            if (typeof(T) == typeof(sbyte))
            {
                return (T)((object)((sbyte)((object)left) - (sbyte)((object)right)));
            }
            if (typeof(T) == typeof(sfloat))
            {
                return (T)((object)((sfloat)((object)left) - (sfloat)((object)right)));
            }
            if (typeof(T) == typeof(ushort))
            {
                return (T)((object)((ushort)((object)left) - (ushort)((object)right)));
            }
            if (typeof(T) == typeof(uint))
            {
                return (T)((object)((uint)((object)left) - (uint)((object)right)));
            }
            if (typeof(T) == typeof(ulong))
            {
                return (T)((object)((ulong)((object)left) - (ulong)((object)right)));
            }
            //ThrowHelper.ThrowNotSupportedException(ExceptionResource.Arg_TypeNotSupported);
            return default(T);
        }
    }
}